
#ifndef CAMPROCESS_H
#define CAMPROCESS_H

#include <caros/hand_detection/global.h>
#include <opencv2/opencv.hpp>

#include <map>
#include <string>
#include <vector>

struct processResult
{
  int x;
  int y;
  double radius;
  bool valid;
};

class CameraProcessing
{
 public:
  explicit CameraProcessing();
  ~CameraProcessing();
  CameraProcessing(CameraProcessing const&) = delete;
  CameraProcessing& operator=(CameraProcessing const&) = delete;

  void init(unsigned int CAM_HEIGHT_, unsigned int CAM_WIDTH_);
  bool isInit()
  {
    return is_init_;
  }
  void processImg(const cv::Mat& src, cv::Mat& dst);
  void setParameters(const std::string& _parameterId, const int& _value);
  processResult getResult()
  {
    return latest_result_;
  }

 private:
  static void matDeleter(void* mat)
  {
    delete static_cast<cv::Mat*>(mat);
  }
  void updateParameters();
  void initTracker(double _noiseCov);
  void trackCenter(cv::Point& _point, double& _radius);

 public:
  // void imageReady(std::vector<uchar> _image);
  void sendCenterPosition(const int& _x, const int& _y, const double& _r);
  void sendFingers(const std::vector<int>& _fingers);
  void sendVector(int _label, const std::vector<double>& _vector);

 private:
  // QImage m_imageOut;
  std::map<std::string, int> m_parameters_;
  cv::Mat m_blended_;
  cv::Mat m_temp1_8U_, m_temp0_32F_, m_temp0_64F_;
  cv::Mat m_flood_fill_8U_;
  cv::Mat m_distance_8U_;
  std::vector<double> m_theta_vector_;
  std::vector<double> m_theta_conv_;
  std::vector<double> m_conv_kernel_;
  std::vector<int> m_peaks_;
  cv::KalmanFilter* m_tracker_;
  cv::Mat m_tracker_measurement_;
  cv::Mat m_tracker_prediction_;
  double m_tracker_ticks_;

  int m_output_;
  double m_blend_;
  double m_sigma_;
  int m_median_;
  int m_threshold_;
  float m_search_multiplier_;

  unsigned int CAM_HEIGHT_, CAM_WIDTH_;

  bool is_init_;
  bool lost_track_;
  processResult latest_result_;
};

#endif /* CAMPROCESS_H */
